﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Kokomo.Mirror.CliMetadata;

namespace Kokomo.PeInspector.Reflection.Disassembly
{
	/// <summary>
	/// Represents a dependency on a field from MSIL.
	/// </summary>
	public class MsilFieldDependency : MsilMemberDependency
	{
		public FieldInfo GetFieldDependency()
		{
			return (FieldInfo)this.GetMemberDependency();
		}

		/// <summary>
		/// Gets the usage of the field.
		/// </summary>
		/// <seealso cref="MsilVariableReferenceType"/>
		public MsilVariableReferenceType Usage { get; private set; }

		/// <summary>
		/// Initializes a new instance of <see cref="MsilFieldDependency"/>.
		/// </summary>
		/// <param name="offset">The offset of the instruction causing the dependency.</param>
		/// <param name="field">The field dependency.</param>
		/// <param name="usage">The usage of the field.</param>
		/// <seealso cref="MsilVariableReferenceType"/>
		private MsilFieldDependency(
			Module targetModule,
			int metadataToken,
			MsilVariableReferenceType usage,
			int offset
			)
			: base(targetModule, metadataToken, offset)
		{
			this.Usage = usage;
		}

		public static MsilFieldDependency FromField(
			FieldInfo field,
			MsilVariableReferenceType usage,
			int offset = 0
			)
		{
			if (field == null) throw new ArgumentNullException("field");
			return new MsilFieldDependency(field.Module, field.MetadataToken, usage, offset);
		}
		public static MsilFieldDependency FromFieldRef(
			ModuleMemberReference fieldRef,
			MsilVariableReferenceType usage,
			int offset = 0
			)
		{
			if (ModuleMemberReference.IsEmpty(fieldRef)) throw new ArgumentNullException("fieldRef");
			return new MsilFieldDependency(fieldRef.Module, fieldRef.MetadataToken, usage, offset);
		}
	}
}
